/*
 * Copyright (c) 2003-2010, Live Media Pty. Ltd.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, this list of
 *     conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list of
 *     conditions and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *  3. Neither the name of Live Media nor the names of its contributors may be used to endorse
 *     or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.colony.transport;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.argot.network.TypeLink;
import com.argot.remote.transport.TypeEndPoint;
import com.colony.concurrent.ThreadActivator;

public abstract class Server
{
	private TypeLink _back;
	private ThreadActivator _pool;
	
	private static Logger logger = Logger.getLogger( Server.class.getName() );
	
	public Server( TypeLink back, ThreadActivator workerPool )
	{
		_back = back;
		_pool = workerPool;
	}

	public Server( ThreadActivator workerPool )
	{
		this(null,workerPool);
	}
	
	public TypeLink getTypeLink()
	{
		return _back;
	}
	
	public void setTypeLink( TypeLink link )
	{
		_back = link;
	}
	
	public ThreadActivator getPool()
	{
		return _pool;
	}

	protected boolean assignServerThread( TypeEndPoint request )
	{
		return _pool.assignThread( new ServerWorker( request ) );
	}
	
	protected void processMessage( TypeEndPoint request )
	{
		try
		{
			while (true) 
			{
				int magic1 = request.getInputStream().read();
				int magic2 = request.getInputStream().read();
				if (magic1 == 10 && magic2 == 20 )
				{
					_back.processMessage(request);		
				}
				else
				{
					break;
				}
			}
		}
		catch( Throwable t )
		{
			logger.log(Level.SEVERE,"Error in Server", t);
		}
		finally
		{
			processFinish( request );
		}
	}
	
	private class ServerWorker
	implements Runnable
	{
		private TypeEndPoint _request;
		
		public ServerWorker( TypeEndPoint request )
		{
			_request = request;
		}
		
		public void run()
		{
			processMessage( _request );
		}
	}
	
	protected abstract void processFinish( TypeEndPoint request );
}
